/**
 * 
 * JShakki  - Dude with recycled paper..
 * 
 * @version 1.0
 * 
 * Copyright (C) 2006 Jarkko Sipilä
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *  
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *  
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 * 
 */

package dude.data;

import java.awt.Dimension;

public class Square {
  
  public static final int HORIZONTAL = 0;
  public static final int UPWARD = 1;
  public static final int VERTICAL = 2;
  public static final int DOWNWARD = 3;
  
  private char owner; // x, o or -
  private Board board;
  private final Dimension coordinates;
  
  
  protected Square( Dimension d, Board area ) {	
    this.owner = '-';
    this.board = area;
    this.coordinates = d;
  }
   
  
  protected void setLine( Dimension referer, char ownerOfReferer, int direction ) {
    
    if ( ownerOfReferer == this.owner ) {
      // kutsujalla on sama omistaja			
      int kutsuttavaX = this.coordinates.width + (referer.width - this.coordinates.width) * -1;
      int kutsuttavaY = this.coordinates.height + (referer.height - this.coordinates.height) * -1;
      
      // piirretään itsen päälle viiva
      this.board.guiDrawLine( this.coordinates, direction );
      
      // Kutsutaan seuraavaa
      if ( kutsuttavaX >= 0 && kutsuttavaY >= 0 ) {
        // kutsuttava ruutu on pelilaudalla
        Square kutsuttava = this.board.getSquare( new Dimension( kutsuttavaX, kutsuttavaY ) );
        if (kutsuttava != null )
          kutsuttava.setLine( this.coordinates, this.owner, direction );
      }
    }
  }
  
  
  /**
   * Asettaa ruudulle omistajaksi vuorossa olevan pelaajan.
   * Jos ruudulle on jo asetettu omistaja, niin asettaminen ei onnistu 
   */
  protected void setOwner() {
    if (this.owner != '-' )
      return; // on jo omistaja
    
    if ( this.board.isXTurn() )
      this.owner = 'x';
    else
      this.owner = 'o';
    this.board.guiDrawOwner( this.coordinates, this.owner );
    
    
    /* Tarkistetaan joka suuntaan yhtenäiset rivit */
    
    int x = this.coordinates.width;
    int y = this.coordinates.height;

    
    // Horizontal
    int length = 0;
    Square left = null, right = null;
    
    left = this.board.getSquare(new Dimension(x-1, y));
    if (left != null)
      length = left.getLengthOfLine( this.coordinates, this.owner );
    right = this.board.getSquare(new Dimension(x+1, y));
    if (right != null)
      length += right.getLengthOfLine( this.coordinates, this.owner );
    
    if( length >= 4 ) {
      this.board.guiDrawLine( this.coordinates, Square.HORIZONTAL );
      if ( left != null)
        left.setLine( this.coordinates, this.owner, Square.HORIZONTAL );
      if (right != null)
        right.setLine( this.coordinates, this.owner, Square.HORIZONTAL );
    }

    
    // nouseva
    length = 0;	
    left = null; right = null;
    
    left = this.board.getSquare(new Dimension(x-1, y+1));
    if (left != null)
      length = left.getLengthOfLine( this.coordinates, this.owner );
    right = this.board.getSquare(new Dimension(x+1, y-1));
    if (right != null)
      length += right.getLengthOfLine( this.coordinates, this.owner );
    
    if( length >= 4 ) {
      this.board.guiDrawLine( this.coordinates, Square.UPWARD );
      if ( left != null)
        left.setLine( this.coordinates, this.owner, Square.UPWARD );
      if (right != null)
        right.setLine( this.coordinates, this.owner, Square.UPWARD );
    }
    
    
    // vertical   
    length = 0;	
    left = null; right = null;

    left = this.board.getSquare(new Dimension(x, y+1)); // ylä
    if (left != null)
      length = left.getLengthOfLine( this.coordinates, this.owner );
    right = this.board.getSquare(new Dimension(x, y-1)); // ala
    if (right != null)
      length += right.getLengthOfLine( this.coordinates, this.owner );
    
    if( length >= 4 ) {
      this.board.guiDrawLine( this.coordinates, Square.VERTICAL );
      if ( left != null)
        left.setLine( this.coordinates, this.owner, Square.VERTICAL );
      if (right != null)
        right.setLine( this.coordinates, this.owner, Square.VERTICAL );
    }
    
 
    // LASKEVA
    length = 0;	
    left = null; right = null;
    
    left = this.board.getSquare(new Dimension(x-1, y-1)); 
    if (left != null)
      length = left.getLengthOfLine( this.coordinates, this.owner );
    right = this.board.getSquare(new Dimension(x+1, y+1));
    if (right != null)
      length += right.getLengthOfLine( this.coordinates, this.owner );
    
    if( length >= 4 ) {
      this.board.guiDrawLine( this.coordinates, Square.DOWNWARD );
      if ( left != null)
        left.setLine( this.coordinates, this.owner, Square.DOWNWARD );
      if (right != null)
        right.setLine( this.coordinates, this.owner, Square.DOWNWARD );
    }
      
    this.board.changeTurn();
    
  }

  
  private int getLengthOfLine( Dimension referer, char ownerOfReferer ) {
    
    if ( ownerOfReferer == this.owner ) {
      // kutsujalla on sama omistaja
      
      int kutsuttavaX = this.coordinates.width + (referer.width - this.coordinates.width) * -1;
      int kutsuttavaY = this.coordinates.height + (referer.height - this.coordinates.height) * -1;
      
      if ( kutsuttavaX >= 0 && kutsuttavaY >= 0 ) {
        Square kutsuttava = this.board.getSquare( new Dimension(kutsuttavaX, kutsuttavaY) );
        if ( kutsuttava != null)
          return 1 + kutsuttava.getLengthOfLine( this.coordinates, this.owner );
        else
          return 1;
      }
      else
        return 1; // meni yli reunojen
    }
    else
      return 0; // kutsujalla eri omistaja
  }
}
